<template>
	<div class="pagination">
		<button
			type="button"
			class="btn-prev"
			@click="prev"
			:disabled="currentPage <= 1"
		>
			<i class="iconfont icon-left"></i>
		</button>
		<ul class="pagination-pager" @click="setCurrentPage">
			<li :class="{ number: true, active: currentPage === 1 }">1</li>
			<li
				class="iconfont icon-ellipsis"
				v-show="startEnd.start > 2"
				@click="jumpPrev"
			></li>
			<!-- <li class="number">6</li>
			<li class="number">7</li>
			<li class="number active">8</li>
			<li class="number">9</li>
			<li class="number">10</li> -->
			<li
				:class="{
					number: true,
					active: currentPage === startEnd.start + index,
				}"
				v-for="(_number, index) in startEnd.end - startEnd.start + 1"
				:key="startEnd.start + index"
			>
				{{ startEnd.start + index }}
			</li>
			<li
				class="iconfont icon-ellipsis"
				v-show="startEnd.end < totalPages - 1"
				@click="jumpNext"
			></li>
			<li
				v-if="totalPages > 1"
				:class="{ number: true, active: currentPage === totalPages }"
			>
				{{ totalPages }}
			</li>
		</ul>
		<button
			type="button"
			class="btn-next"
			@click="next"
			:disabled="currentPage >= totalPages"
		>
			<i class="iconfont icon-right"></i>
		</button>
	</div>
</template>

<script>
export default {
	name: "PaginationComp",
	props: {
		// 总数
		total: {
			type: Number,
			default: 100,
		},
		// 当前页码
		currentPage: {
			type: Number,
			default: 1,
		},
		// 每页条数
		pageSize: {
			type: Number,
			default: 1,
		},
	},
	computed: {
		totalPages() {
			return Math.ceil(this.total / this.pageSize);
		},
		startEnd() {
			const { currentPage, totalPages } = this;

			/*
        场景一：
          1 ... 6 7 [8] 9 10 ... 100
          计算startEnd
            start = currentPage - 2
            end = currentPage + 2
            或
            end = start + 4
        
        场景二：
          1 2 [3] 4 5 6 ... 100
          计算startEnd：
            start = currentPage - 2 = 3 - 2 = 1
            end = start + 4 = 1 + 4 = 5
            计算结果有问题，怎么办？
            解决: start代表的是中间按钮的起始，是有最小值的，就是2
            if (start < 2) start = 2

        场景三：
          1 ... 95 96 97 98 [99] 100
          计算startEnd：
            start = currentPage - 2 = 99 - 2 = 97
            end = start + 4 = 97 + 4 = 101
            计算结果有问题，怎么办？
            解决: end代表的是中间按钮的结束，是有最大值的，就是 totalPages - 1
            if (end > totalPages - 1) {
              end = totalPages - 1
              start = end - 4
            }

        场景四：
          1 2 3 [4] 5 6
          计算结果有问题，怎么办？
          小于等于7个按钮，就不需要计算了，直接返回值

          if (totalPages <= 7) {
            return {
              start: 2,
              end: totalPages - 1
            }
          }
        
        场景五：
          [1]
          [1] 2
          这种场景不需要中间按钮？end - start + 1 === 0

          if (totalPages <= 2) {
            return {
              start: 1,
              end: 0
            }
          }
      */

			if (totalPages <= 2) {
				return {
					start: 2,
					end: 1,
				};
			}

			if (totalPages <= 7) {
				return {
					start: 2,
					end: totalPages - 1,
				};
			}

			let start = currentPage - 2;
			if (start < 2) start = 2;
			let end = start + 4;
			if (end > totalPages - 1) {
				end = totalPages - 1;
				start = end - 4;
			}

			return {
				start,
				end,
			};
		},
	},
	methods: {
		// 向前翻页
		prev() {
			// props数据是只读的，不能直接修改
			// this.currentPage--;
			this.$emit("update:currentPage", this.currentPage - 1);
		},
		// 向后翻页
		next() {
			// props数据是只读的，不能直接修改
			// this.currentPage++;
			this.$emit("update:currentPage", this.currentPage + 1);
		},
		// 设置页码
		setCurrentPage(e) {
			const number = +e.target.textContent.trim();
			// 排除 0 和 NaN, 它们取布尔值都是false
			if (!number) return;
			if (number === this.currentPage) return;
			this.$emit("update:currentPage", number);
		},
		// 向前翻5页
		jumpPrev() {
			let number = this.currentPage - 5;
			if (number < 1) number = 1;
			this.$emit("update:currentPage", number);
		},
		// 向后翻5页
		jumpNext() {
			let number = this.currentPage + 5;
			if (number > this.totalPages) number = this.totalPages;
			this.$emit("update:currentPage", number);
		},
	},
	watch: {
		currentPage(currentPage) {
			this.$emit("current-change", currentPage, this.pageSize);
		},
	},
};
</script>

<style lang="less">
.pagination {
	padding-top: 20px;
	display: flex;
	justify-content: center;
	font-weight: 700;
	white-space: nowrap;
	button {
		border: none;
		display: inline-block;
		font-size: 13px;
		min-width: 30px;
		height: 28px;
		line-height: 28px;
		vertical-align: top;
		box-sizing: border-box;
		cursor: pointer;
		margin: 0 5px;
		&[disabled] {
			cursor: not-allowed;
			color: #c0c4cc;
		}
	}
}
.pagination-pager {
	display: flex;

	.btn-next,
	.btn-prev,
	li {
		margin: 0 5px;
		background-color: #f4f4f5;
		color: #606266;
		min-width: 30px;
		border-radius: 2px;
		padding: 0 4px;
		vertical-align: top;
		display: inline-block;
		font-size: 13px;
		height: 28px;
		line-height: 28px;
		cursor: pointer;
		box-sizing: border-box;
		text-align: center;
		&:hover {
			color: #409eff;
		}
		&.active {
			background-color: #409eff;
			color: #fff;
		}
	}
}
</style>